package com.vcens.dingnotice.service.impl;

import com.vcens.dingnotice.entity.TaskEntity;
import com.vcens.dingnotice.exception.RestException;
import com.vcens.dingnotice.repository.TaskerMapper;
import com.vcens.dingnotice.service.ITaskerService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author vechar
 */
@Service
@Transactional
@Slf4j
public class TaskerServiceImpl implements ITaskerService {

    @Autowired
    private TaskerMapper taskerMapper;

    @Autowired
    private Scheduler scheduler;

    @Override
    public void buildTask(TaskEntity taskEntity) throws RestException {
        log.info("DingNotice Init Task has been initialized...");
        //创建任务信息
        try {
            Class cls = Class.forName(taskEntity.getClassName());

            cls.newInstance();
            JobDetail job = JobBuilder.newJob(cls).withIdentity(taskEntity.getName(),
                    taskEntity.getGroup())
                    .withDescription(taskEntity.getDesc()).build();
            //传递ID过去，用来查询
            job.getJobDataMap().put("JOBID", taskEntity.getId());
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(taskEntity.getCronExpression());
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(taskEntity.getName(), taskEntity.getGroup())
                    .startNow().withSchedule(cronScheduleBuilder).build();
            scheduler.scheduleJob(job, trigger);
        } catch (Exception e) {
            throw new RestException("构建任务异常");
        }
    }

    @Override
    public TaskEntity findById(Object jobid) {
        return null;
    }

    @Override
    public void triggerTask(TaskEntity taskEntity) throws RestException {
        JobKey key = new JobKey(taskEntity.getName(), taskEntity.getGroup());
        try {
            scheduler.triggerJob(key);
        } catch (SchedulerException e) {
            throw new RestException("开启任务失败");
        }
    }

    @Override
    public List<TaskEntity> listByPage(TaskEntity taskEntity, Integer cp, Integer pageSize) {
        return null;
    }

    @Override
    public void pauseTask(TaskEntity taskEntity) throws RestException {
        JobKey key = new JobKey(taskEntity.getName(), taskEntity.getGroup());
        try {
            scheduler.pauseJob(key);
        } catch (SchedulerException e) {
            throw new RestException("暂停任务失败");
        }
    }

    @Override
    public void resumeTask(TaskEntity taskEntity) throws RestException {
        JobKey key = new JobKey(taskEntity.getName(), taskEntity.getGroup());
        try {
            scheduler.resumeJob(key);
        } catch (SchedulerException e) {
            throw new RestException("恢复任务失败");
        }
    }

    @Override
    public void removeTask(TaskEntity taskEntity) throws RestException {
        TriggerKey triggerKey = TriggerKey.triggerKey(taskEntity.getName(), taskEntity.getGroup());
        // 停止触发器
        try {
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);
            // 删除任务
            scheduler.deleteJob(JobKey.jobKey(taskEntity.getName(), taskEntity.getGroup()));
        } catch (SchedulerException e) {
            throw new RestException("删除任务失败");
        }
    }

    @Override
    public List<Map<String, Object>> list() throws RestException {
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        Set<JobKey> jobKeys = null;
        List<Map<String, Object>> jobList = new ArrayList<>();
        try {
            jobKeys = scheduler.getJobKeys(matcher);
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    Map<String, Object> job = new HashMap<>();
                    job.put("Name", jobKey.getName());
                    job.put("group", jobKey.getGroup());
                    //下次触发时间
                    job.put("NextTime", trigger.getNextFireTime());
                    //上次触发时间
                    job.put("lastTime", trigger.getPreviousFireTime());
                    //开始时间
                    job.put("startTime", trigger.getStartTime());
                    //trigger.getEndTime();//结束时间
                    //触发器当前状态
                    Trigger.TriggerState triggerState = null;
                    try {
                        triggerState = scheduler.getTriggerState(trigger.getKey());
                    } catch (SchedulerException e) {
                        e.printStackTrace();
                    }
                    job.put("triggerState", triggerState.name());
                    //任务表达式
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        job.put("cronExpression", cronExpression);
                    }
                    jobList.add(job);
                }
            }
        } catch (SchedulerException e) {
            throw new RestException("获取任务列表异常");
        }
        return jobList;
    }

}
